Skip to content

feat(android): Add queryable getFramesDelay API to SentryFrameMetricsCollector#5248

Merged
antonis merged 10 commits intomainfrom
feat/queryable-frames-delay-api
Apr 30, 2026
Merged

feat(android): Add queryable getFramesDelay API to SentryFrameMetricsCollector#5248
antonis merged 10 commits intomainfrom
feat/queryable-frames-delay-api

Conversation

@antonis
Copy link
Copy Markdown
Contributor

@antonis antonis commented Mar 30, 2026

📜 Description

Add a queryable getFramesDelay(startSystemNanos, endSystemNanos) API to SentryFrameMetricsCollector that returns a SentryFramesDelayResult containing the total frame delay (in seconds) and the number of frames contributing to the delay for a given time range.

This mirrors iOS's existing SentryFramesTracker.getFramesDelaySPI and allows external consumers to query frame delay without registering a duplicate frame listener.

Changes:

  • New SentryFramesDelayResult data class with delaySeconds and framesContributingToDelayCount
  • New getFramesDelay() method on SentryFrameMetricsCollector with frame buffer, 5-minute auto-pruning, and partial overlap handling
  • Accessible via the existing options.getFrameMetricsCollector().getFramesDelay(...) — no new getters needed

💡 Motivation and Context

The React Native SDK needs to query frame delay for arbitrary time ranges (see getsentry/sentry-react-native#5908). Currently it registers its own RNSentryFrameDelayCollector as a listener on SentryFrameMetricsCollector, duplicating the work already done internally — double listener callbacks, double storage, and redundant computation on the UI thread.

With this API, the RN SDK can delete RNSentryFrameDelayCollector (~130 lines) and replace it with a single getFramesDelay() call, keeping only the startCollection/stopCollection lifecycle it already manages.

💚 How did you test it?

  • 6 new unit tests in SentryFrameMetricsCollectorTest covering: unavailable state, invalid ranges, zero delay, slow/frozen frame delay, partial frame overlap, and automatic pruning of old frames
  • All 46 existing + new tests pass (30 SentryFrameMetricsCollector + 16 SpanFrameMetricsCollector)

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

#skip-changelog

antonis and others added 2 commits March 30, 2026 12:43
…llector

Expose a getFramesDelay(startNanos, endNanos) method that allows
external consumers (e.g. React Native SDK) to query frame delay for
arbitrary time ranges without registering a duplicate frame listener.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against df1f7a6

@sentry
Copy link
Copy Markdown

sentry Bot commented Mar 30, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.40.0 (1) release

⚙️ sentry-android Build Distribution Settings

Copy link
Copy Markdown
Contributor Author

@antonis antonis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the changelog since I guess this is only useful for our own SDKs

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 312.18 ms 367.40 ms 55.22 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
5865051 319.74 ms 365.60 ms 45.86 ms
cf708bd 408.35 ms 458.98 ms 50.63 ms
b750b96 408.98 ms 480.32 ms 71.34 ms
1df7eb6 397.04 ms 429.64 ms 32.60 ms
9ea89e8 308.06 ms 358.16 ms 50.10 ms
319f256 315.96 ms 372.96 ms 57.00 ms
c8125f3 383.82 ms 441.66 ms 57.84 ms
f064536 327.04 ms 405.35 ms 78.31 ms
b3d8889 420.46 ms 453.71 ms 33.26 ms
f064536 335.52 ms 408.79 ms 73.27 ms

App size

Revision Plain With Sentry Diff
5865051 0 B 0 B 0 B
cf708bd 1.58 MiB 2.11 MiB 539.71 KiB
b750b96 1.58 MiB 2.10 MiB 533.19 KiB
1df7eb6 1.58 MiB 2.10 MiB 532.97 KiB
9ea89e8 1.58 MiB 2.28 MiB 716.23 KiB
319f256 1.58 MiB 2.19 MiB 619.79 KiB
c8125f3 1.58 MiB 2.10 MiB 532.32 KiB
f064536 1.58 MiB 2.20 MiB 633.90 KiB
b3d8889 1.58 MiB 2.10 MiB 535.07 KiB
f064536 1.58 MiB 2.20 MiB 633.90 KiB

Previous results on branch: feat/queryable-frames-delay-api

Startup times

Revision Plain With Sentry Diff
6ed2e89 372.10 ms 438.49 ms 66.39 ms
3603793 321.94 ms 352.89 ms 30.95 ms
a4b2f1c 327.71 ms 396.00 ms 68.29 ms

App size

Revision Plain With Sentry Diff
6ed2e89 0 B 0 B 0 B
3603793 0 B 0 B 0 B
a4b2f1c 0 B 0 B 0 B

@antonis antonis marked this pull request as ready for review March 30, 2026 11:31
@markushi
Copy link
Copy Markdown
Member

@antonis this looks very promising! Before diving any further: The Android SDK only collects frame metrics when there's a span active (see e.g. onSpanStarted), will the RN side take care of calling those APIs?

@antonis antonis marked this pull request as draft March 30, 2026 12:14
@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Mar 30, 2026

The Android SDK only collects frame metrics when there's a span active (see e.g. onSpanStarted), will the RN side take care of calling those APIs?

Thank you for raising this @markushi 🙇 This indeed complicates things since the whole point of this PR was to simplify the RN implementation in getsentry/sentry-react-native#5907

I'll convert this back to draft to revist and iterate back. Thank you for having a first look.

@markushi
Copy link
Copy Markdown
Member

@antonis I just had another look and I think if we have two options here:

  1. Access the APIs on a different level
    Instead of using SpanFrameMetricsCollector we could use the underlying SentryFrameMetricsCollector directly and add a new getFramesDelay(final long startSystemNanos, final long endSystemNanos) method there.

  2. Create virtual spans
    Use SpanFrameMetricsCollector but have a single "virtual" RN span which starts / stops whenever any span is running on the RN side.

I think 1. should be simpler and cleaner to implement, so I'd go for that.

@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Mar 31, 2026

  1. Access the APIs on a different level
    Instead of using SpanFrameMetricsCollector we could use the underlying SentryFrameMetricsCollector directly and add a new getFramesDelay(final long startSystemNanos, final long endSystemNanos) method there.

Thank you for looking into this @markushi 🙇 That makes sense 👍 I'll iterate on this.

antonis and others added 2 commits March 31, 2026 15:33
Moves the queryable frames delay API from SpanFrameMetricsCollector
to SentryFrameMetricsCollector per review feedback. This avoids
coupling the API to span lifecycle, making it directly usable by
hybrid SDKs via the already-accessible options.getFrameMetricsCollector().

Reverts changes to SpanFrameMetricsCollector, SentryAndroidOptions,
and AndroidOptionsInitializer from the previous approach.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 1, 2026

@sentry review

@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 1, 2026

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@antonis antonis changed the title feat(android): Add queryable getFramesDelay API to SpanFrameMetricsCollector feat(android): Add queryable getFramesDelay API to SentryFrameMetricsCollector Apr 1, 2026
@antonis antonis marked this pull request as ready for review April 1, 2026 08:14
@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 1, 2026

Thank you for your help @markushi 🙇 This is ready for another pass 🤞

…unnecessarily

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1a28507. Configure here.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@markushi markushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@antonis antonis merged commit 61659b6 into main Apr 30, 2026
66 of 67 checks passed
@antonis antonis deleted the feat/queryable-frames-delay-api branch April 30, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants